﻿package com.designoutput.elements
{
	import com.designoutput.enum.ElementType;
	import com.designoutput.utils.Unit;
	import com.designoutput.utils.UnitUtils;
	
	import flash.geom.Point;

	/**
	 * Just the Free form line element
	 * 
	 */	
	public class PolyLineElement extends BaseRectElement
	{
		private var _points:Array;
		private var _currentPoints:Array;
		private var m_nDefW:Number;
		private var m_nDefH:Number;

		public function PolyLineElement()
		{
			super();
			_points = [];
			_currentPoints = [];
			m_nDefW=0;
			m_nDefH=0;
		}
		
		override public function getClassName():String{
			return ElementType.PolyLineElement; 
		}

		public function addPoint(nX:Number, nY:Number):void
		{
			_points.push(new Point(nX,nY));
			invalidateElement();
		}

		public function setPoints(arrPoints:Array):void
		{
			_points = arrPoints.slice();
			invalidateElement();
		}

		public function updateByShape():void
		{
			if (_points.length < 1)
				return;
			var nMinX:Number=_points[0].x;
			var nMinY:Number=_points[0].y;
			var nMaxX:Number=nMinX;
			var nMaxY:Number=nMinY;
			for (var i:Number=1; i < _points.length; i++)
			{
				if (nMinX > _points[i].x)
					nMinX=_points[i].x;
				if (nMinY > _points[i].y)
					nMinY=_points[i].y;
				if (nMaxX < _points[i].x)
					nMaxX=_points[i].x;
				if (nMaxY < _points[i].y)
					nMaxY=_points[i].y;
			}
			for (var j:Number=0; j < _points.length; j++)
			{
				_points[j].x-=nMinX;
				_points[j].y-=nMinY;
			}
			width = nMaxX - nMinX;
			height = nMaxY - nMinY;
			m_nDefW=_width;
			m_nDefH=_height;
		}
		
		private function updateCurrentPoints():void {
			var kx:Number=_width / m_nDefW;
			var ky:Number=_height / m_nDefH;
			_currentPoints = new Array(_points.length);
			for (var i:Number=0; i < _points.length; i++)
				_currentPoints[i] = new Point(Math.floor(_points[i].x * kx), Math.floor(_points[i].y * ky));
		}

		override protected function updateElement():void
		{
			super.updateElement();
			
			updateCurrentPoints();
			
			this.graphics.clear();
			if (useFill && useLine){
				fillPolyLine(this, _currentPoints, this.fillColor, this.fillAlpha, useLine ? this.lineColor : undefined, this.lineAlpha, this.lineSize);
				drawPolyLine(this, _currentPoints, this.lineColor, this.lineAlpha, this.lineSize);
			} else if (useLine && !useFill){
				drawPolyLine(this, _currentPoints, this.lineColor, this.lineAlpha, this.lineSize);
			}else if(!useLine && useFill){
				fillPolyLine(this, _currentPoints, this.fillColor, this.fillAlpha, useLine ? this.lineColor : undefined, this.lineAlpha, this.lineSize);
			}else{
				fillPolyLine(this, _currentPoints, this.fillColor, 0, useLine ? this.lineColor : undefined, this.lineAlpha, this.lineSize);
			}
		}

		override public function toXML():XML
		{
			var xmlNode:XML = super.toXML();
			
			xmlNode.@defW = m_nDefW;
			xmlNode.@defH = m_nDefH;
			
			var pointsNode:XML = <points />;
			for (var i:Number=0; i < _points.length; i++)
				pointsNode.appendChild(<point x={_points[i].x} y={_points[i].y} />);
			
			xmlNode.appendChild(pointsNode);
			
			return xmlNode;
		}

		override public function fromXML(xmlNode:XML):void
		{
			super.fromXML(xmlNode);
			m_nDefW = xmlNode.@defW;
			m_nDefH = xmlNode.@defH;
			
			if(xmlNode.points.length() > 0){
				_points = new Array();
				
				for each(var pointNode:XML in xmlNode.points.point){
					_points.push( new Point( Number(pointNode.@x), Number(pointNode.@y) ) );
				}
			}

			updateElement();
		}
	}
}